from flask import Flask, request, jsonify, session, send_from_directory
import mysql.connector
from werkzeug.security import generate_password_hash, check_password_hash
import os
from datetime import date, timedelta

app = Flask(__name__, template_folder='templates', static_folder='static')
app.secret_key = os.environ.get('FLASK_SECRET_KEY', 'dev_secret_key_please_change_in_prod')
app.permanent_session_lifetime = timedelta(days=7)

DB_CONFIG = {
    'host': "192.168.40.43",
    'user': "root",
    'password': "Root123!",
    'database': "program",
    'raise_on_warnings': True
}


def get_db_connection():
    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        return conn
    except mysql.connector.Error as err:
        app.logger.error(f"数据库连接失败: {err}")
        return None


@app.before_request
def make_session_permanent():
    session.permanent = True


@app.route('/')
def index():
    return send_from_directory('templates', 'index.html')


@app.route('/register', methods=['POST'])
def register_api():
    username = request.form.get('username', '').strip()
    password = request.form.get('password', '')
    email = request.form.get('email', '').strip()

    if not username or not password:
        return jsonify({"success": False, "error": "用户名和密码不能为空!"}), 400
    if len(password) < 6:
        return jsonify({"success": False, "error": "密码长度至少为6位!"}), 400

    conn = get_db_connection()
    if not conn:
        return jsonify({"success": False, "error": "数据库服务暂时不可用。"}), 500

    cursor = conn.cursor()
    try:
        cursor.execute("SELECT id FROM web_users WHERE username = %s", (username,))
        if cursor.fetchone():
            return jsonify({"success": False, "error": "用户名已被注册，请选择其他用户名。"}), 409  # 409 Conflict

        if email:
            cursor.execute("SELECT id FROM web_users WHERE email = %s", (email,))
            if cursor.fetchone():
                return jsonify({"success": False, "error": "该邮箱已被注册，请使用其他邮箱。"}), 409

        hashed_password = generate_password_hash(password)
        cursor.execute(
            "INSERT INTO web_users (username, password_hash, email) VALUES (%s, %s, %s)",
            (username, hashed_password, email if email else None)
        )
        conn.commit()
        return jsonify({"success": True, "message": "恭喜您，注册成功！现在可以登录了。"})
    except mysql.connector.Error as err:
        conn.rollback()
        app.logger.error(f"注册时数据库错误: {err}")
        return jsonify({"success": False, "error": f"注册过程中发生错误，请稍后再试。"}), 500
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()


@app.route('/login', methods=['POST'])
def login_api():
    username = request.form.get('username', '').strip()
    password = request.form.get('password', '')

    if not username or not password:
        return jsonify({"success": False, "error": "请输入用户名和密码。"}), 400

    conn = get_db_connection()
    if not conn:
        return jsonify({"success": False, "error": "数据库服务暂时不可用。"}), 500

    cursor = conn.cursor(dictionary=True)
    try:

        cursor.execute("SELECT student_id FROM student_info WHERE student_id = %s", (username,))
        student = cursor.fetchone()
        if not student:
            return jsonify({"success": False, "error": "用户名（学号）不存在"}), 401

        cursor.execute("SELECT id, username, password_hash FROM web_users WHERE username = %s", (username,))
        user = cursor.fetchone()

        if user and check_password_hash(user['password_hash'], password):
            session['user_id'] = user['id']
            session['username'] = user['username']  # 此处存储学号
            app.logger.info(f"用户 '{username}' 登录成功。Session: {session}")
            return jsonify({
                "success": True,
                "username": user['username'],
                "message": f"欢迎回来, {user['username']}!"
            })
        else:
            return jsonify({"success": False, "error": "密码错误"}), 401
    except mysql.connector.Error as err:
        app.logger.error(f"登录时数据库错误: {err}")
        return jsonify({"success": False, "error": "登录过程中发生错误，请稍后再试。"}), 500
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

@app.route('/logout', methods=['POST'])
def logout_api():
    session.pop('user_id', None)
    session.pop('username', None)
    app.logger.info(f"用户已登出。Session: {session}")
    return jsonify({"success": True, "message": "您已成功退出登录。"})


@app.route('/api/auth_status')
def auth_status_api():
    if 'user_id' in session and 'username' in session:
        app.logger.debug(f"Auth status check: Logged in as {session['username']}. Session: {session}")
        return jsonify({"authenticated": True, "username": session.get('username')})
    else:
        app.logger.debug(f"Auth status check: Not logged in. Session: {session}")
        return jsonify({"authenticated": False})

def execute_query(query, params=None, fetch_one=False):
    conn = get_db_connection()
    if not conn:
        return None, "数据库连接失败"

    cursor = conn.cursor(dictionary=True)
    data = None
    error_message = None
    try:
        cursor.execute(query, params)
        if fetch_one:
            data = cursor.fetchone()
        else:
            data = cursor.fetchall()
        if data:
            if isinstance(data, list):
                for row in data:
                    if row and isinstance(row.get('dob'), date):
                        row['dob'] = row['dob'].isoformat()
            elif isinstance(data, dict):  # For fetch_one
                if data and isinstance(data.get('dob'), date):
                    data['dob'] = data['dob'].isoformat()
    except mysql.connector.Error as err:
        app.logger.error(f"数据库查询错误 (Query: {query}, Params: {params}): {err}")
        error_message = "查询数据时发生内部错误"
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()
    return data, error_message

@app.route('/api/students/info/<student_id>')
def api_student_info(student_id):
    if 'user_id' not in session:
        return jsonify({"error": "用户未授权"}), 401

    query = "SELECT student_id, class_id, name, gender, dob, latest_semester, latest_gpa, status FROM student_info WHERE student_id = %s"
    student_data, error = execute_query(query, (student_id,), fetch_one=True)

    if error:
        return jsonify({"error": error}), 500
    if student_data:
        return jsonify(student_data)
    else:
        return jsonify({"error": "未找到该学号的学生信息"}), 404

@app.route('/api/students/search')
def api_search_students():
    if 'user_id' not in session:
        return jsonify({"error": "用户未授权"}), 401

    query_term = request.args.get('q', '').strip()
    if not query_term:
        return jsonify({"error": "搜索词不能为空"}), 400
    if len(query_term) < 1:
        return jsonify({"error": "搜索词至少需要1个字符"}), 400

    search_pattern = f"%{query_term}%"
    query = """
        SELECT student_id, name, class_id, latest_gpa, status
        FROM student_info
        WHERE student_id LIKE %s OR name LIKE %s
        LIMIT 15
    """
    results, error = execute_query(query, (search_pattern, search_pattern))

    if error:
        return jsonify({"error": error}), 500
    return jsonify(results)

@app.route('/api/students/similar/<student_id>')
def api_similar_students(student_id):
    if 'user_id' not in session:
        return jsonify({"error": "用户未授权"}), 401

    query = """
        SELECT rec.recommended_student_id, rec.score, rec.rank, 
               info.name, info.latest_gpa
        FROM cf_recommendations rec
        JOIN student_info info ON rec.recommended_student_id = info.student_id
        WHERE rec.user_student_id = %s
        ORDER BY rec.rank ASC
        LIMIT 6 
    """
    similar_students, error = execute_query(query, (student_id,))

    if error:
        return jsonify({"error": error}), 500
    return jsonify(similar_students)

@app.route('/api/students/top')
def api_top_students():
    if 'user_id' not in session:
        return jsonify({"error": "用户未授权"}), 401

    query = "SELECT `rank`, student_id, name, latest_gpa FROM top_students ORDER BY `rank` ASC LIMIT 3"
    top_students_data, error = execute_query(query)

    if error:
        return jsonify({"error": error}), 500
    return jsonify(top_students_data)

if __name__ == '__main__':
    is_dev_env = os.environ.get('FLASK_ENV', 'production').lower() == 'development'
    app.run(host='0.0.0.0', port=5000, debug=is_dev_env)